﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Spring.Data.Core;
using Spring.Data.Common;
using NHibernate.Driver;
using NHibernate.Dialect;
using System.Data;
using NHibernate.Cfg.ConfigurationSchema;
using NHibernate.Engine;
using NHibernate.Mapping;
using NHibernate.Cfg;
using System.IO;
using NHibernate.Mapping.Attributes;

namespace HPFCommon.Data.Ado
{
    /// <summary>
    /// 
    /// </summary>
    public class AdoDao : AdoDaoSupport//Spring.Data.Generic.
    {
        private SchemaUpdateStrategy m_Strategy=SchemaUpdateStrategy.UPDATE;
        public SchemaUpdateStrategy Strategy
        {
            get
            {
                return m_Strategy;
            }
            set
            {
                m_Strategy = value;
            }
        }
        private Dialect m_Dialect = new MsSql2005Dialect();
        public Dialect Dialect
        {
            get
            {
                return m_Dialect;
            }
            set
            {
                m_Dialect = value;
            }
        }

        public AdoDao()
        {
        }

        public AdoDao(IDictionary<string, string> props, String schemaUpdateStrategy)
        {

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dialect"></param>
        /// <remarks>
        /// Dictionary<string, string> props = new Dictionary<string, string>();
        /// props[Environment.Dialect] = "\r\n\t "
        ///                  + typeof(MsSql2000Dialect).AssemblyQualifiedName
        ///                  + " \t\r\n  ";
        /// </remarks>
        public void SetDialect(IDictionary<string, string> props)
        {
            m_Dialect=Dialect.GetDialect(props);
        }

        public void SetSchemaUpdateStrategy(String schemaUpdateStrategy)
        {
            this.m_Strategy = (SchemaUpdateStrategy)Enum.Parse(typeof(SchemaUpdateStrategy), schemaUpdateStrategy);
        }


        public void UpdateSchema(Type type, SchemaUpdateStrategy strategy)
        {
            if (strategy == SchemaUpdateStrategy.NONE)
            {
                return;
            }
            bool tableExist = true;
            if (strategy == SchemaUpdateStrategy.UPDATE)
            {
                try
                {
                    this.AdoTemplate.ExecuteNonQuery(CommandType.Text, new StringBuilder().Append("select 1 from ").Append(DPAHelper.GetTableName(type)).ToString());
                }
                catch(Exception ex)
                {
                    tableExist = false;
                    Console.WriteLine(ex.ToString());
                }
            }

            if (!tableExist && strategy == SchemaUpdateStrategy.UPDATE)
            {
                return;
            }
            createTable(type, tableExist);
        }
        public void CreateTable(Type type, bool tableExist)
        {
            
            Configuration config=new Configuration();
            config.AddInputStream(HbmSerializer.Default.Serialize(type));
            IMapping map = config.BuildMapping();
            config.BuildMappings();
            string defaultCatalog = config.Properties["hibernate.default_catalog"];
            string defaultSchema = config.Properties["hibernate.default_schema"];
            Table table = GetTable(config, m_Dialect);
            //ReSortTableColumn(table, m_Dialect, map);

            string sql = "";
            if (tableExist)
            {
                sql = table.SqlDropString(m_Dialect, defaultCatalog, defaultSchema);
                this.AdoTemplate.ExecuteNonQuery(CommandType.Text, sql);
            }
            sql = table.SqlCreateString(m_Dialect,map, defaultCatalog, defaultSchema);
            this.AdoTemplate.ExecuteNonQuery(CommandType.Text, sql);

            IEnumerable<Index> indexs= table.IndexIterator;
            foreach (Index index in indexs)
            {
                sql = index.SqlCreateString(m_Dialect, map, defaultCatalog, defaultSchema);
                this.AdoTemplate.ExecuteNonQuery(CommandType.Text, sql);
            }
        }
            
        public void createTable(Type type, bool tableExsist)
        {
            Configuration config = new Configuration();
            MemoryStream stream = HbmSerializer.Default.Serialize(type);
            stream.Position=0;
            config.AddInputStream(stream);
        }
        public Table GetTable(Configuration config, Dialect dialect)
        {
            return null;
        }

        public void ReSortTableColumn(Table table, Dialect dialect, IMapping map)
        {
        }

    }
}
